﻿using AbpVnext_Module.Permission;
using Ebusiness_Application;
using Ebusiness_Application.Permission;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Volo.Abp.Account;
using Volo.Abp.Authorization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.AutoMapper;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.TenantManagement;
//using Volo.Abp.TenantManagement;

namespace AbpVnext__Comon
{
    /// <summary>
    /// 所有的项目，抽象成AbpModule
    /// 方便使用和维护。
    ///  项目服务隔离 ，好处：独立维护
    /// </summary>
    [DependsOn(typeof(ApplicationContractsMoudule)
        , typeof(DomainMoudule)
        , typeof(AbpAutoMapperModule)
                //配置应用模块
                , typeof(AbpPermissionManagementApplicationModule)
                , typeof(AbpIdentityApplicationModule)
                  , typeof(AbpAccountApplicationModule)
         //配置应用身份认证模块
         , typeof(AbpPermissionManagementDomainIdentityModule)
        , typeof(AbpTenantManagementApplicationModule)  //应用模块 多租户
        ,typeof(AbpFeatureManagementApplicationModule)  //特征 应用模块
        )]
    public class ApplicationMoudule : AbpModule
    {
        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="context"></param>
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            //base.ConfigureServices(context); 依赖注入 代码注册
            //context.Services.AddTransient<IUserService, UserService>();

            //context.Services.AddTransient<IProductAppService, ProductAppService>();


            //配置automap dto映射
            Configure<AbpAutoMapperOptions>(option => option.AddMaps<ApplicationMoudule>());

            #region 应用权限模块原理
            {
                //1、权限定义原理。
                //IPermissionDefinitionManager(提供权限）
                //------ > IStaticPermissionDefinitionStore
                //------ > IPermissionDefinitionProvider
                //----->PermissionDefinition


                //存储
                //2、权限存储原理。定义的权限。存储到数据库
                //AbpPermissionManagementDomainModule
                //------>IStaticPermissionSaver
                //---- > IStaticPermissionDefinitionStore
                //---- > IPermissionDefinitionRecordRepository
                //---- > IPermissionGroupDefinitionRecordRepository


                //3、权限授权原理。就是从权限表中，把权限存储到sys_permissiongrants
                //IPermissionManager
                //----->IPermissionDefinitionManager(提供权限)
                //---- > IPermissionManagementProvider--->UserEamilPermissionManagementProvider
                //---- > UserPermissionManagementProvider
                //---- > RolePermissionManagementProvider
                //Name （权限提供者自定义）
                //----->IPermissionGrantRepository--->EfCorePermissionGrantRepository
                //（权限存储）


                //4、鉴权原理。 根据用户信息查询sys_permissiongrants表是否有授权数据。
                //IAbpAuthorizationService--->AbpAuthorizationService
                //---- > AbpAuthorizationServiceExtensions
                //----->IAuthorizationService--->DefaultAuthorizationService
                //---- > IAuthorizationHandler--->PermissionRequirementHandler

                //（核心代码）
                //----> IPermissionChecker-- PermissionChecker
                //---- > IsGrantedAsync（）方法
                //--->PermissionDefinitionManager(查询定义的权限)
                //---- > IPermissionValueProviderManager
                //--->IPermissionValueProvider---- > UserEamilPermissionValueProvider "UserEamil"
                //---- > UserPermissionValueProvider"U"
                //---- > RolePermissionValueProvider "R"
                //---- > ClientPermissionValueProvider "C"

                //Volo.Abp.PermissionManagement.Domain(权限管理模块)
                //--->IPermissionStore(去数据库查询，查询权限) （具体的实现）----> PermissionStore
                //---- > IPermissionGrantRepository
                //----->IDistributedCache(分布式缓存)默认存储在本地



                //5、特性鉴权原理 配置特性方式授权。AOP。
                //AuthorizationInterceptorRegistrar---- > 注册拦截哪一个特性。以及哪一个拦截器
                //---- > AuthorizationInterceptor---- > --> AbpInterceptor(Volo.Abp.DynamicProxy 命名空间中)
                //---- > IMethodInvocationAuthorizationService
                //---- > MethodInvocationAuthorizationService(进行鉴权)
                //---- > AlwaysAllowMethodInvocationAuthorizationService(不进行鉴权)
                //--->IAbpAuthorizationServi
            }
            #endregion
            //配置自定义鉴权类
            Configure<AbpPermissionOptions>(option =>
            {
                //当注册多个权限值提供者时，PermissionGrantResult.Prohibited;
                //当其中有一个返回值为Prohibited，会直接返回403，授权没有通过
                //当返回值没有Prohibited,其中有一个返回值为Granted,则代表授权通过
                //当返回值全部为Undefined,,则代表授权没有通过
                //option.ValueProviders.Add(typeof(CustomPermissionValueProvider));
                //option.ValueProviders.Add(typeof(ProductPermissionValueProvider));
                option.ValueProviders.Add(typeof(UserEmaillPermissionValueProvider));
                //option.ValueProviders.Clear();
            });

            //注册自定义用户邮箱权限管理提供者
            Configure<PermissionManagementOptions>(option =>
            {
                option.ManagementProviders.Add<UserEmaillPermissionManagementProvider>();
            });
        }
    }
}
